/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tbenglish_client.form;

import bllInterface.ChatMessage;
import bllInterface.ChatMessageContent;
import bllfactory.SBLLFactory;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.UnsupportedEncodingException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.text.DefaultCaret;
import model.ClientFriendListModel;
import model.ClientModel;
import model.chat.ChatMessageModel;

/**
 *
 * @author Mrkupi
 */
public class privateChat extends javax.swing.JFrame implements ListDataListener {

    private ClientFriendListModel model;
    private DefaultListModel newModel = new DefaultListModel();
    private ArrayList<String> strModel = new ArrayList();
    
    private String friendId;
    private String friendName;
    
    public privateChat(ChatMessageModel msgModel, String friendID, String friendName) {
        initComponents();
        
        setResizable(false);
        
        // HARD CODED
        setLocation(400, 200);

        this.friendName = friendName;
        this.friendId   = friendID;
        
        msgModel.addListDataListener(this);
        this.lblFriendName.setText(friendName);

        initWindowCustomize();
        loadUserInfo();
        // Load history
        //loadRoomHistory();
    }

    @Override
    public void dispose(){
        if( RoomContainer.Container.containsKey( friendId ) )
            RoomContainer.Container.remove( friendId );
        super.dispose();
    }
    
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        taChatbox = new javax.swing.JTextArea();
        tfChat = new javax.swing.JTextField();
        btEnter = new javax.swing.JButton();
        pnMyAvatar = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        tfName = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        tfLevel = new javax.swing.JLabel();
        tfExp = new javax.swing.JLabel();
        lblFriendName = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("PRIVATE CHAT");

        taChatbox.setEditable(false);
        taChatbox.setColumns(20);
        taChatbox.setRows(5);
        jScrollPane1.setViewportView(taChatbox);

        tfChat.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                onEnter_pressed(evt);
            }
        });

        btEnter.setText("Enter");
        btEnter.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                onEnter_clicked(evt);
            }
        });

        pnMyAvatar.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        jButton1.setIcon(new javax.swing.ImageIcon("E:\\Projects\\Java\\tbenglish\\TBEnglish_Client\\src\\tbenglish_client\\form\\Image\\HEINS_DESKTOP_LOOKUPS BRUCE.png")); // NOI18N

        jLabel1.setText("Nick name");

        tfName.setText("jLabel3");

        jLabel3.setText("Level");

        jLabel4.setText("Exp");

        tfLevel.setText("jLabel5");

        tfExp.setText("jLabel5");

        javax.swing.GroupLayout pnMyAvatarLayout = new javax.swing.GroupLayout(pnMyAvatar);
        pnMyAvatar.setLayout(pnMyAvatarLayout);
        pnMyAvatarLayout.setHorizontalGroup(
            pnMyAvatarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnMyAvatarLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnMyAvatarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(pnMyAvatarLayout.createSequentialGroup()
                        .addGroup(pnMyAvatarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel3)
                            .addComponent(jLabel1)
                            .addComponent(jLabel4))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(pnMyAvatarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(tfName)
                            .addComponent(tfLevel)
                            .addComponent(tfExp)))
                    .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        pnMyAvatarLayout.setVerticalGroup(
            pnMyAvatarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnMyAvatarLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(pnMyAvatarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(tfName))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnMyAvatarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(tfLevel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnMyAvatarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(tfExp))
                .addGap(20, 20, 20))
        );

        lblFriendName.setText("Name");

        jLabel2.setText("Friend:");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(tfChat)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 365, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(btEnter, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(pnMyAvatar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(8, 8, 8)
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(lblFriendName)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap(24, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblFriendName)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(pnMyAvatar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 226, Short.MAX_VALUE))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(tfChat, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btEnter))
                .addGap(26, 26, 26))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void onEnter_pressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_onEnter_pressed
        if( evt.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER )
        {
            sendMessageToFriend( tfChat.getText() );
            tfChat.setText("");
        }
    }//GEN-LAST:event_onEnter_pressed

    private void onEnter_clicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_onEnter_clicked
            sendMessageToFriend( tfChat.getText() );
            tfChat.setText("");
    }//GEN-LAST:event_onEnter_clicked

    private boolean sendMessageToFriend( String message ){
        // NEED TABLE
        if (!makeSureNotEmptyTextField()) {
            return false;
        }
        try {
            ChatMessage cm = ChatMessage.createMessage(ClientModel.getInstance().getAccount().getUserID(), message, this.friendId);
            SBLLFactory.getInstance().getServerChat().post(cm);
            publishNewMessageToTextArea(cm);
        } catch (RemoteException ex) {
            Logger.getLogger(roomChat.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(this, "Connection error!!");
        }

        return true;
    }
    
    private boolean makeSureNotEmptyTextField(){
        if( "".equals( tfChat.getText() ))
        {
            JOptionPane.showMessageDialog( this, "" );
            return false;
        }
        
        return true;
    }
    
    private void publishNewMessageToTextArea(ChatMessage message) {
        this.taChatbox.append("\n" + String.format("%s: %s", message.getSender(), message.getContent().get(ChatMessageContent.MESSAGE_CONTENT)));
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btEnter;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel lblFriendName;
    private javax.swing.JPanel pnMyAvatar;
    private javax.swing.JTextArea taChatbox;
    private javax.swing.JTextField tfChat;
    private javax.swing.JLabel tfExp;
    private javax.swing.JLabel tfLevel;
    private javax.swing.JLabel tfName;
    // End of variables declaration//GEN-END:variables
    
    protected void initWindowCustomize() {
        setResizable(false);
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                dispose();
            }
        });

        taChatbox.setWrapStyleWord(true);
        DefaultCaret dc = (DefaultCaret) taChatbox.getCaret();
        dc.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
    }

    protected void loadRoomHistory() {
        try {
            ArrayList<ChatMessage> messages = bllfactory.SBLLFactory.getInstance().getChat().getRoom(this.friendId).getHistory();
            for (ChatMessage cm : messages) {
                this.taChatbox.append("\n" + String.format("%s: %s", cm.getSender(), cm.getContent().get(ChatMessageContent.MESSAGE_CONTENT)));
            }
        } catch (RemoteException ex) {
            System.out.println("Error load history");
        }
    }

    protected void loadUserInfo(){
        try {
            this.tfName.setText(new String(ClientModel.getInstance().getAccount().getUserName().getBytes(), "UTF-8"));

            this.tfExp.setText(String.valueOf(ClientModel.getInstance().getAccount().getExp()));
            this.tfLevel.setText(String.valueOf(ClientModel.getInstance().getAccount().getLevel()));
        } catch (RemoteException | UnsupportedEncodingException ex) {
            Logger.getLogger(userInfo.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    @Override
    public void intervalAdded(ListDataEvent e) {
        if (e.getSource() instanceof ChatMessageModel) {
            ChatMessageModel chatMsgModel = (ChatMessageModel) e.getSource();
            try {
                for (int i = e.getIndex0(); i < e.getIndex1(); ++i) {
                    ChatMessage cm = (ChatMessage) chatMsgModel.getElementAt(i);
                    if (cm.getSender() == null ? ClientModel.getInstance().getAccount().getUserID() != null : !cm.getSender().equals(ClientModel.getInstance().getAccount().getUserID())) {
                        this.publishNewMessageToTextArea(cm);
                    }
                }
            } catch (RemoteException ex) {
                Logger.getLogger(roomChat.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    @Override
    public void intervalRemoved(ListDataEvent e) {
    }

    @Override
    public void contentsChanged(ListDataEvent e) {
    }
}
